package com.distribute.framework.core.web.helper;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.distribute.framework.core.web.helper.Utils;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;



@SuppressWarnings({ "serial", "unchecked" })
public final class JsonHelper{
	
	public static String serialVersionE = "B2D9C4E3C2E8";
		
	/**
	 * json	解析
	 * @param jsonString
	 * @return
	 */
	public static <T> T eval(String jsonString){
		if(Utils.empty(jsonString))
			return null;
		jsonString = jsonString.trim();
		if(jsonString.startsWith("[")){
			JSONArray jsonArray = (JSONArray) JSONArray.parse(jsonString);
			return (T) JSONArrayToList(jsonArray);
		}else{
			JSONObject jsonObject = (JSONObject) JSONObject.parse(jsonString);
			return (T) JSONObjectToMap(jsonObject);
		}
	}
	
	/**
	 * 把JSONObject转成Map格式
	 * @param jsonObject
	 * @return
	 * @throws JSONException 
	 */
	public static Map JSONObjectToMap(JSONObject jsonObject){		
		Map map=new HashMap();
		Iterator<String> keys = jsonObject.keySet().iterator();
		while(keys.hasNext()){
			String key = keys.next();
			Object value = jsonObject.get(key);
			if(value==null)continue;
			if(value instanceof JSONObject){
				map.put(key, JSONObjectToMap((JSONObject) value));
			}else if(value instanceof JSONArray){
				map.put(key, JSONArrayToList((JSONArray) value));				
			}else
				map.put(key,value);		
		}		
		return map;
	}
	/**
	 * 把JSONArray转成List
	 * @param value
	 * @return
	 * @throws JSONException 
	 */
	public static List JSONArrayToList(JSONArray jsonArray){
		List list = new ArrayList();		
		for(int i=0;i<jsonArray.size();i++){
			Object value = jsonArray.get(i);
			if(value == null){
				continue;
			}else if(value instanceof JSONObject){
				list.add(JSONObjectToMap((JSONObject) value));
			}else if(value instanceof JSONArray){
				list.add( JSONArrayToList((JSONArray) value));			
			}else
				list.add(value);
		}		
		return list;
	}
	
	
	public static class a{
		Date d = new Date();
		String $ddd = "";
		public Date getD() {
			return d;
		}
		public void setD(Date d) {
			this.d = d;
		}
		public String getDc(){
			return "afdfds";
		}
	}
	
	public static void main(String...strings){
		List list = new ArrayList();
		list.add(new a());
		list.add(new a());
		list.add(new a());
		Utils.trace(json(list));
		
		Utils.trace(json(new a[]{
				new a(),
				new a()
		}));
	}
	
	
	static ThreadLocal local = new ThreadLocal();//加入线程栈，防止递归调用 
	public static String json(Object object){
		/*if(local.get()==null)
			local.set(new ArrayList());
		ArrayList jsoned = (ArrayList) local.get();
		if(jsoned.indexOf(object)>-1)
			return "null";
		else
			jsoned.add(object);*/
		if(object==null)
			return "null";
		Class cls = object.getClass();
		if(cls.getSimpleName().indexOf("byte[]")>-1 || cls.getSimpleName().indexOf("short[]")>-1 || cls.getSimpleName().indexOf("int[]")>-1)
			return cls.getSimpleName();
		else if(cls.getSuperclass()==java.lang.Number.class || cls==java.lang.Boolean.class)
			return ""+object;
		else if(object instanceof java.util.Map)
			return map((Map) object);
		else if(object instanceof java.util.List)
			return list((List) object);
		else if(cls.isArray())
			return array((Object[]) object);
		else if(cls == java.lang.String.class || cls == java.lang.Character.class)
			return "\""+js((String) object)+"\"";
		else if(object instanceof java.util.Date)
			return ""+((Date)object).getTime();
		else{
			return object(object).toString();
		}
	}

	private static String list(List list) {
		String strJson="";
		for(Object object:list){
			if(!empty(strJson))
				strJson+=",";
			strJson+=json(object);
		}
		return "["+strJson+"]";
	}


	protected static String map(Map map) {
		String strJson="";		
		Set<String> keySet = map.keySet();
		for(String key:keySet){
			Object value = map.get(key);
			if(value==null)continue;
			if(!empty(strJson))
				strJson+=",";
			strJson+="\""+js(key)+"\":"+json(map.get(key));
		}
		return "{"+strJson+"}";
	}
	
	
	protected static String array(Object[] array) {		
		String strJson="";
		for(Object object:array){
			if(!empty(strJson))
				strJson+=",";
			strJson+=json(object);
		}
		return "["+strJson+"]";
	}
	
	
	protected static String object(Object object) {
		String strJson="";
		
		Field[] fields = object.getClass().getDeclaredFields();
		for(Field field:fields)
		{
			field.setAccessible(true);
			String fieldName = field.getName();
			Method method=null;
			try {
				method = object.getClass().getMethod("get"+ForMat(fieldName));
			} catch (Exception e) {}
			if(method==null){
				try {
					method = object.getClass().getMethod("is"+ForMat(fieldName));
				} catch (Exception e) {} 
			}
			if(method==null)
				continue;
			
			/*Object fieldObject=null;
			try {
				fieldObject = method.invoke(object);
			} catch (Exception e) {} */
			Object fieldObject=null;
			try {
				fieldObject = field.get(object);
			} catch (Exception e) {} 
			if(fieldObject==null)
				continue;
			if(fieldObject==object)
				continue;
			if(!WebHelper.empty(strJson))
				strJson+=",";
			strJson+="\""+WebHelper.js(fieldName)+"\":"+json(fieldObject);
		}
		
		return "{"+strJson+"}";
	}
	
	protected static String ForMat(String string)
	{
		if(string==null || string.equals(""))
			return string;
		return string.substring(0,1).toUpperCase() + string.substring(1);
	}
	
	protected static String forMat(String string)
	{
		if(string==null || string.equals(""))
			return string;
		return string.substring(0,1).toLowerCase() + string.substring(1);
	}
	
	protected static String format(String string)
	{
		if(string==null || string.equals(""))
			return string;
		return string.toLowerCase();		
	}
	
	protected static String FORMAT(String string)
	{
		if(string==null || string.equals(""))
			return string;
		return string.toUpperCase();		
	}
	
	protected static String Format(String string)
	{
		if(string==null || string.equals(""))
			return string;
		string=string.toLowerCase();
		return string.substring(0,1).toUpperCase() + string.substring(1);
	}
	
	public static String js(String string){
		if(string==null || string.trim().equals(""))
			return "";
		string=string.replaceAll("\\\\", "\\\\\\\\");
		string=string.replaceAll("\\n", "\\\\n");
		string=string.replaceAll("\\r", "\\\\r");
		//string=string.replaceAll("\\'", "\\\\'");
		string=string.replaceAll("\\\"", "\\\\\"");	
		/*string=string.replace("\\", "\\\\");
		string=string.replace("\n", "\\n");
		string=string.replace("\r", "\\r"); 
		string=string.replaceAll("\"", "\\\"");*/
		
		return string;
	}	
	
	public static Boolean empty(String string)
	{
		if(string==null || string.trim().equals(""))
			return true;
		return false;		
	}
}